<article class="" id="post-">
<header class="entry-header">
<h1 class="entry-title">jQuery.Callbacks()</h1>
<div class="entry-meta">
						所属分类：<span class="category"><a href="/category/callbacks-object/">回调对象</a></span>
<span class="pull-right">英文文档：<a href="https://api.jquery123.com/jQuery.Callbacks/" target="_blank">jQuery.Callbacks()</a></span>
</div><!-- .entry-meta -->
</header><!-- .entry-header -->
<!-- .entry-header -->
<div class="entry-content">
<article class="entry method" id="jQuery-Callbacks1"><h2 class="section-title">
<span class="name">jQuery.Callbacks( flags )</span><span class="returns">返回: <a href="/Types/#Callbacks">Callbacks</a></span>
</h2>
<div class="entry-wrapper">
<p class="desc"><strong>描述: </strong>一个多用途的回调列表对象，提供了强大的的方式来管理回调函数列表。</p>
<ul class="signatures"><li class="signature" id="jQuery-Callbacks-flags">
<h4 class="name">
<span class="version-details">添加的版本: <a href="/category/version/1.7/">1.7</a></span>jQuery.Callbacks( flags )</h4>
<ul><li>
<div><strong>flags</strong></div>
<div>类型: <a href="/Types/#String">String</a>
</div>
<div>一个用空格标记分隔的标志可选列表,用来改变回调列表中的行为。</div>
</li></ul>
</li></ul>
<div class="longdesc" id="entry-longdesc">
<p><code>$.Callbacks()</code>的内部提供了jQuery的<code>$.ajax()</code> 和 <code>$.Deferred()</code> 基本功能组件。它可以用来作为类似基础定义的新组件的功能。</p>
<p><code>$.Callbacks()</code> 支持的方法，包括 <code><a href="/callbacks.add">callbacks.add()</a></code>,<code><a href="/callbacks.remove">callbacks.remove()</a></code>, <code><a href="/callbacks.fire">callbacks.fire()</a></code> and <code><a href="/callbacks.disable">callbacks.disable()</a></code>.</p>
<h3 id="getting-started">Getting started(入门)</h3>
<p>以下是两个样品的方法命名<code>fn1</code> 和 <code>fn2</code>:</p>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="function"><span class="keyword">function</span> <span class="title">fn1</span><span class="params">( value )</span> {</span></code></div></div><div class="container"><div class="line"><code>    console.log( value );</code></div></div><div class="container"><div class="line"><code>}</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="function"><span class="keyword">function</span> <span class="title">fn2</span><span class="params">( value )</span> {</span></code></div></div><div class="container"><div class="line"><code>    fn1(<span class="string">"fn2 says: "</span> + value);</code></div></div><div class="container"><div class="line"><code>    <span class="keyword">return</span> <span class="literal">false</span>;</code></div></div><div class="container"><div class="line"><code>}</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>这些可以添加为回调函数作为一个<code>$.Callbacks</code>的列表，并调用如下:</p>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="keyword">var</span> callbacks = $.Callbacks();</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// outputs: foo!</span></code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foo!"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code>callbacks.add( fn2 );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// outputs: bar!, fn2 says: bar!</span></code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"bar!"</span> );</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>这样做的结果是，它使构造复杂的回调列表变得简单，输入值可以通过尽可能多的函数根据需要轻松使用。</p>
<p>用于以上的两个具体的方法：
			 <code>.add()</code> 和 <code>.fire()</code> .add() 支持添加新的回调回调列表, 而<code>.fire()</code> 提供了一种用于处理在同一列表中的回调方法的途径.</p>
<p>另一种方法由<code>$.Callbacks</code> 的<code>.remove()</code>，用于从回调列表中删除一个特定的回调。下面是.remove() 使用的一个例子:</p>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
<div class="line n13">13</div>
<div class="line n14">14</div>
<div class="line n15">15</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="keyword">var</span> callbacks = $.Callbacks();</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// outputs: foo!</span></code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foo!"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code>callbacks.add( fn2 );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// outputs: bar!, fn2 says: bar!</span></code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"bar!"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code>callbacks.remove( fn2 );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// only outputs foobar, as fn2 has been removed.</span></code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foobar"</span> );</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<h3 id="supported-flags">Supported Flags（支持的 Flags）</h3>
<p>这个 <code>flags</code> 参数是<code>$.Callbacks()</code>的一个可选参数, 结构为一个用空格标记分隔的标志可选列表,用来改变回调列表中的行为 (比如. <code>$.Callbacks( 'unique stopOnFalse' )</code>).</p>
<h2>Possible flags:（可用的 flags:）</h2>
<ul>
<li> <code>once</code>: 确保这个回调列表只执行（ .fire() ）一次(像一个递延 Deferred).</li>
<li> <code>memory</code>: 保持以前的值，将添加到这个列表的后面的最新的值立即执行调用任何回调  (像一个递延 Deferred).</li>
<li> <code>unique</code>: 确保一次只能添加一个回调(所以在列表中没有重复的回调).</li>
<li> <code>stopOnFalse</code>: 当一个回调返回false 时中断调用</li>
</ul>
<p>默认情况下，回调列表将像事件的回调列表中可以多次触发。</p>
<p>如何在理想情况下应该使用的<code>flags</code>的例子，见下文：</p>
<h2 id="once">
<code>$.Callbacks( "once" )</code>:</h2>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="keyword">var</span> callbacks = $.Callbacks( <span class="string">"once"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foo"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"bar"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.remove( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foobar"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">/*</span></code></div></div><div class="container"><div class="line"><code>output:</code></div></div><div class="container"><div class="line"><code>foo</code></div></div><div class="container"><div class="line"><code>*/</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<h2 id="memory">
<code>$.Callbacks( "memory" )</code>:</h2>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
<div class="line n13">13</div>
<div class="line n14">14</div>
<div class="line n15">15</div>
<div class="line n16">16</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="keyword">var</span> callbacks = $.Callbacks( <span class="string">"memory"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foo"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"bar"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.remove( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foobar"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">/*</span></code></div></div><div class="container"><div class="line"><code>output:</code></div></div><div class="container"><div class="line"><code>foo</code></div></div><div class="container"><div class="line"><code>fn2 says:foo</code></div></div><div class="container"><div class="line"><code>bar</code></div></div><div class="container"><div class="line"><code>fn2 says:bar</code></div></div><div class="container"><div class="line"><code>foobar</code></div></div><div class="container"><div class="line"><code>*/</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<h2 id="unique">
<code>$.Callbacks( "unique" )</code>:</h2>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
<div class="line n13">13</div>
<div class="line n14">14</div>
<div class="line n15">15</div>
<div class="line n16">16</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="keyword">var</span> callbacks = $.Callbacks( <span class="string">"unique"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foo"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 ); <span class="comment">// repeat addition</span></code></div></div><div class="container"><div class="line"><code>callbacks.add( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"bar"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.remove( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foobar"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">/*</span></code></div></div><div class="container"><div class="line"><code>output:</code></div></div><div class="container"><div class="line"><code>foo</code></div></div><div class="container"><div class="line"><code>bar</code></div></div><div class="container"><div class="line"><code>fn2 says:bar</code></div></div><div class="container"><div class="line"><code>foobar</code></div></div><div class="container"><div class="line"><code>*/</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<h2 id="stopOnFalse">
<code>$.Callbacks( "stopOnFalse" )</code>:</h2>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
<div class="line n13">13</div>
<div class="line n14">14</div>
<div class="line n15">15</div>
<div class="line n16">16</div>
<div class="line n17">17</div>
<div class="line n18">18</div>
<div class="line n19">19</div>
<div class="line n20">20</div>
<div class="line n21">21</div>
<div class="line n22">22</div>
<div class="line n23">23</div>
<div class="line n24">24</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="function"><span class="keyword">function</span> <span class="title">fn1</span><span class="params">( value )</span>{</span></code></div></div><div class="container"><div class="line"><code>    console.log( value );</code></div></div><div class="container"><div class="line"><code>    <span class="keyword">return</span> <span class="literal">false</span>;</code></div></div><div class="container"><div class="line"><code>}</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="function"><span class="keyword">function</span> <span class="title">fn2</span><span class="params">( value )</span>{</span></code></div></div><div class="container"><div class="line"><code>    fn1( <span class="string">"fn2 says: "</span> + value );</code></div></div><div class="container"><div class="line"><code>    <span class="keyword">return</span> <span class="literal">false</span>;</code></div></div><div class="container"><div class="line"><code>}</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="keyword">var</span> callbacks = $.Callbacks( <span class="string">"stopOnFalse"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foo"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"bar"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.remove( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foobar"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">/*</span></code></div></div><div class="container"><div class="line"><code>output:</code></div></div><div class="container"><div class="line"><code>foo</code></div></div><div class="container"><div class="line"><code>bar</code></div></div><div class="container"><div class="line"><code>foobar</code></div></div><div class="container"><div class="line"><code>*/</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>
			        因为<code>$.Callbacks()</code> 支持一个列表的flags（标识）而不仅仅是一个，设置几个flags（标识），有一个累积效应，类似“&amp;&amp;”。这意味着它可能结合创建回调名单，<i>unique</i> 和<i>确保如果名单已经触发，将有更多的回调调用最新的触发值</i> (i.e. <code>$.Callbacks("unique memory")</code>).</p>
<h2 id="unique-memory">
<code>$.Callbacks( 'unique memory' )</code>:</h2>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
<div class="line n13">13</div>
<div class="line n14">14</div>
<div class="line n15">15</div>
<div class="line n16">16</div>
<div class="line n17">17</div>
<div class="line n18">18</div>
<div class="line n19">19</div>
<div class="line n20">20</div>
<div class="line n21">21</div>
<div class="line n22">22</div>
<div class="line n23">23</div>
<div class="line n24">24</div>
<div class="line n25">25</div>
<div class="line n26">26</div>
<div class="line n27">27</div>
<div class="line n28">28</div>
<div class="line n29">29</div>
<div class="line n30">30</div>
<div class="line n31">31</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="function"><span class="keyword">function</span> <span class="title">fn1</span><span class="params">( value )</span> {</span></code></div></div><div class="container"><div class="line"><code>    console.log( value );</code></div></div><div class="container"><div class="line"><code>    <span class="keyword">return</span> <span class="literal">false</span>;</code></div></div><div class="container"><div class="line"><code>}</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="function"><span class="keyword">function</span> <span class="title">fn2</span><span class="params">( value )</span> {</span></code></div></div><div class="container"><div class="line"><code>    fn1( <span class="string">"fn2 says: "</span> + value );</code></div></div><div class="container"><div class="line"><code>    <span class="keyword">return</span> <span class="literal">false</span>;</code></div></div><div class="container"><div class="line"><code>}</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="keyword">var</span> callbacks = $.Callbacks( <span class="string">"unique memory"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foo"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn1 ); <span class="comment">// repeat addition</span></code></div></div><div class="container"><div class="line"><code>callbacks.add( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"bar"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.add( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"baz"</span> );</code></div></div><div class="container"><div class="line"><code>callbacks.remove( fn2 );</code></div></div><div class="container"><div class="line"><code>callbacks.fire( <span class="string">"foobar"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">/*</span></code></div></div><div class="container"><div class="line"><code>output:</code></div></div><div class="container"><div class="line"><code>foo</code></div></div><div class="container"><div class="line"><code>fn2 says:foo</code></div></div><div class="container"><div class="line"><code>bar</code></div></div><div class="container"><div class="line"><code>fn2 says:bar</code></div></div><div class="container"><div class="line"><code>baz</code></div></div><div class="container"><div class="line"><code>fn2 says:baz</code></div></div><div class="container"><div class="line"><code>foobar</code></div></div><div class="container"><div class="line"><code>*/</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>
			        Flag结合体是使用的<code>$.Callbacks()</code>内部的<code>.done()</code> 和 <code>.fail()</code>一个递延容器-它们都使用 <code>$.Callbacks('memory once')</code>.
			    </p>
<p> <code>$.Callbacks</code> 方法也可以被分离, 为方便起见应该有一个需要定义简写版本：</p>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="keyword">var</span> callbacks = $.Callbacks(),</code></div></div><div class="container"><div class="line"><code>    add = callbacks.add,</code></div></div><div class="container"><div class="line"><code>    remove = callbacks.remove,</code></div></div><div class="container"><div class="line"><code>    fire = callbacks.fire;</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code>add( fn1 );</code></div></div><div class="container"><div class="line"><code>fire( <span class="string">"hello world"</span> );</code></div></div><div class="container"><div class="line"><code>remove( fn1 );</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<h3 id="pubsub">$.Callbacks, $.Deferred and Pub/Sub</h3>
<p>pub / sub（观察者模式）背后的一般思路 是促进应用程序的松散耦合。而比对其他对象的方法调用的单个对象，一个对象，而不是另一个对象的一个特定的任务或活动，并通知当它发生。观察家也被称为订阅者，它指向观察对象。观察者（Publisher）事件发生时通知用户</p>
<p>作为 <code>$.Callbacks()</code> 的创建组件的一个演示，只使用回调函数列表，就可以实现 Pub/Sub 系统。将 <code>$.Callbacks</code> 作为一个文章队列，可以向下面这样，实现文章的发布和订阅：</p>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
<div class="line n13">13</div>
<div class="line n14">14</div>
<div class="line n15">15</div>
<div class="line n16">16</div>
<div class="line n17">17</div>
<div class="line n18">18</div>
<div class="line n19">19</div>
<div class="line n20">20</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="keyword">var</span> topics = {};</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code>jQuery.Topic = <span class="keyword">function</span>( id ) {</code></div></div><div class="container"><div class="line"><code>    <span class="keyword">var</span> callbacks,</code></div></div><div class="container"><div class="line"><code>        method,</code></div></div><div class="container"><div class="line"><code>        topic = id &amp;&amp; topics[ id ];</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code>    <span class="keyword">if</span> ( !topic ) {</code></div></div><div class="container"><div class="line"><code>        callbacks = jQuery.Callbacks();</code></div></div><div class="container"><div class="line"><code>        topic = {</code></div></div><div class="container"><div class="line"><code>            publish: callbacks.fire,</code></div></div><div class="container"><div class="line"><code>            subscribe: callbacks.add,</code></div></div><div class="container"><div class="line"><code>            unsubscribe: callbacks.remove</code></div></div><div class="container"><div class="line"><code>        };</code></div></div><div class="container"><div class="line"><code>        <span class="keyword">if</span> ( id ) {</code></div></div><div class="container"><div class="line"><code>            topics[ id ] = topic;</code></div></div><div class="container"><div class="line"><code>        }</code></div></div><div class="container"><div class="line"><code>    }</code></div></div><div class="container"><div class="line"><code>    <span class="keyword">return</span> topic;</code></div></div><div class="container"><div class="line"><code>};</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>然后，可以很容易的使用这部分应用程序的发布和订阅感兴趣的事件：</p>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
<div class="line n13">13</div>
<div class="line n14">14</div>
<div class="line n15">15</div>
<div class="line n16">16</div>
<div class="line n17">17</div>
<div class="line n18">18</div>
<div class="line n19">19</div>
<div class="line n20">20</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="comment">// Subscribers</span></code></div></div><div class="container"><div class="line"><code>$.Topic( <span class="string">"mailArrived"</span> ).subscribe( fn1 );</code></div></div><div class="container"><div class="line"><code>$.Topic( <span class="string">"mailArrived"</span> ).subscribe( fn2 );</code></div></div><div class="container"><div class="line"><code>$.Topic( <span class="string">"mailSent"</span> ).subscribe( fn1 );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// Publisher</span></code></div></div><div class="container"><div class="line"><code>$.Topic( <span class="string">"mailArrived"</span> ).publish( <span class="string">"hello world!"</span> );</code></div></div><div class="container"><div class="line"><code>$.Topic( <span class="string">"mailSent"</span> ).publish( <span class="string">"woo! mail!"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// Here, "hello world!" gets pushed to fn1 and fn2</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// when the "mailArrived" notification is published</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// with "woo! mail!" also being pushed to fn1 when</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// the "mailSent" notification is published.</span></code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">/*</span></code></div></div><div class="container"><div class="line"><code>output:</code></div></div><div class="container"><div class="line"><code>hello world!</code></div></div><div class="container"><div class="line"><code>fn2 says: hello world!</code></div></div><div class="container"><div class="line"><code>woo! mail!</code></div></div><div class="container"><div class="line"><code>*/</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>
			
			        尽管上面的代码很有用，但是可以进一步改进其实现。使用 <code>$.Deferreds</code>，可以保证当特定的任务被完成（或被解决）时，发布者只能向订阅者发布通知。参见下面的示例代码，进一步讨论如何在实践中使用这种情况：</p>
<div class="syntaxhighlighter javascript nogutter">
<table>
<tbody>
<tr>
<td class="gutter">
<div class="line n1">1</div>
<div class="line n2">2</div>
<div class="line n3">3</div>
<div class="line n4">4</div>
<div class="line n5">5</div>
<div class="line n6">6</div>
<div class="line n7">7</div>
<div class="line n8">8</div>
<div class="line n9">9</div>
<div class="line n10">10</div>
<div class="line n11">11</div>
<div class="line n12">12</div>
<div class="line n13">13</div>
<div class="line n14">14</div>
<div class="line n15">15</div>
<div class="line n16">16</div>
<div class="line n17">17</div>
<div class="line n18">18</div>
<div class="line n19">19</div>
<div class="line n20">20</div>
</td>
<td class="code">
<pre><div class="container"><div class="line"><code><span class="comment">// subscribe to the mailArrived notification</span></code></div></div><div class="container"><div class="line"><code>$.Topic( <span class="string">"mailArrived"</span> ).subscribe( fn1 );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// create a new instance of Deferreds</span></code></div></div><div class="container"><div class="line"><code><span class="keyword">var</span> dfd = $.Deferred();</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// define a new topic (without directly publishing)</span></code></div></div><div class="container"><div class="line"><code><span class="keyword">var</span> topic = $.Topic( <span class="string">"mailArrived"</span> );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// when the deferred has been resolved, publish a</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// notification to subscribers</span></code></div></div><div class="container"><div class="line"><code>dfd.done( topic.publish );</code></div></div><div class="container"><div class="line"><code> </code></div></div><div class="container"><div class="line"><code><span class="comment">// Here the Deferred is being resolved with a message</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// that will be passed back to subscribers. It's possible to</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// easily integrate this into a more complex routine</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// (eg. waiting on an ajax call to complete) so that</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// messages are only published once the task has actually</span></code></div></div><div class="container"><div class="line"><code><span class="comment">// finished.</span></code></div></div><div class="container"><div class="line"><code>dfd.resolve( <span class="string">"it's been published!"</span> );</code></div></div></pre>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div></article> </div>
</article>